<?php

namespace app\service;

use think\facade\Config;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use think\Log;
use util\Logger;

class VolcengineService
{
    protected Client $client;
    protected array $config;

    public function __construct()
    {
//        $api_key      = \app\admin\model\Config::where('name', 'ai_key')->value('value');
        $api_key      = '507f0f93-7133-4bfd-bb2d-12447a153dbc';
        $this->config = [
            'api_key'  => $api_key,
            'base_url' => 'https://ark.cn-beijing.volces.com',
            'model'    => 'deepseek-r1-250120',
        ];
        $this->client = new Client([
            'base_uri' => $this->config['base_url'],
            'timeout'  => 3600,
        ]);
    }

    private function getHeaders()
    {
        return [
            'Content-Type'  => 'application/json',
            'Authorization' => 'Bearer ' . $this->config['api_key'],
        ];
    }

    /**
     * 流式调用
     * @param array $messages
     * @param callable $callback
     * @return mixed
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function streamChatCompletion(array $messages, callable $callback)
    {
        try {
            $response = $this->client->post('/api/v3/chat/completions', [
                'headers' => $this->getHeaders(),
                'json'    => [
                    'model'    => $this->config['model'],
                    'messages' => $messages,
                    'stream'   => true
                ],
                'stream'  => true
            ]);

            $stream      = $response->getBody();
            $buffer      = '';
            $fullContent = '';

            while (!$stream->eof()) {
                $chunk  = $stream->read(1024);
                $buffer .= $chunk;

                // 处理可能跨多个chunk的SSE格式
                while (($pos = strpos($buffer, "\n\n")) !== false) {
                    $event  = substr($buffer, 0, $pos);
                    $buffer = substr($buffer, $pos + 2);

                    foreach (explode("\n", $event) as $line) {
                        $cleanLine = trim($line);
                        if (str_starts_with($cleanLine, 'data: ')) {
                            $jsonStr = substr($cleanLine, 5);
                            // 增加空数据过滤
                            if (empty($jsonStr)) {
                                continue;
                            }
                            if ($jsonStr == '[DONE]') {
                                $callback('', true);
                                return $fullContent;
                            }

                            try {
                                // 增加JSON解析验证
                                $data              = json_decode($jsonStr, true, 512, JSON_THROW_ON_ERROR);
                                $reasoning_content = $data['choices'][0]['delta']['reasoning_content'] ?? '';
                                if (!empty($reasoning_content)) {
                                    $callback('', false, $reasoning_content);
                                }
                                $content = $data['choices'][0]['delta']['content'] ?? '';
                                if (!empty($content)) {
                                    $fullContent .= $content;
                                    $callback($content, false);
                                }
                            } catch (\Exception $e) {
                                // 记录原始错误数据
                                Logger::error("JSON解析失败: {$jsonStr}");
                            }
                        }
                    }
                }
            }

            return $fullContent;
        } catch (RequestException $e) {
            $callback('[请求异常] ' . $e->getMessage(), true);
            return false;
        } catch (\Exception $e) {
            $callback('[系统异常] ' . $e->getMessage(), true);
            return false;
        }
    }

    /**
     * 生成标题
     * @param string $message
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function generateTitle(string $message)
    {
        try {
            $response = $this->client->post('/api/v3/chat/completions', [
                'headers' => $this->getHeaders(),
                'json'    => [
                    'model'    => 'DeepSeek-V3',
                    'messages' => [['role' => 'user', 'content' => "请为以下对话生成一个简短的中文标题，不要使用任何标点符号，不超过15个字：\n" . $message]],
                ]
            ]);
            $body     = json_decode($response->getBody(), true);
            return [
                'success' => true,
                'title'   => $body['choices'][0]['message']['content'] ?? '',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'error'   => $e->getMessage(),
                'code'    => $e->getCode()
            ];
        }
    }

    /**
     * 非流式调用
     * @param array $messages
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function createChatCompletion(array $messages)
    {
        try {
            $response = $this->client->post('/api/v3/chat/completions', [
                'headers' => $this->getHeaders(),
                'json'    => [
                    'model'    => $this->config['model'],
                    'messages' => $messages,
                ]
            ]);
            $body     = json_decode($response->getBody(), true);
            return [
                'success'           => true,
                'reasoning_content' => $body['choices'][0]['message']['reasoning_content'] ?? '',
                'content'           => $body['choices'][0]['message']['content'] ?? '',
                'full_response'     => $body
            ];
        } catch (RequestException $e) {
            return [
                'success' => false,
                'error'   => $e->getMessage(),
                'code'    => $e->getCode()
            ];
        }
    }
}
